#ifndef LIBCOM_SRC_OPVALUE_H
#define LIBCOM_SRC_OPVALUE_H
#include "cmdvalue.h"
#include "data.h"

namespace libxcom {
class OpValue {
public:
    OpValue();
    OpValue(const OpValue &value);
    static OpValue Null();

    OpValue &operator=(const OpValue &value);
    bool IsEmpty() const;

    bool operator!=(const OpValue &value);
    bool operator!=(const TYPE_DEFINE type) const;
    bool operator==(const OpValue &value) const;

    OpValue(int8_t v);
    OpValue(uint8_t v);
    OpValue(int16_t v);
    OpValue(uint16_t v);
    OpValue(int32_t v);
    OpValue(uint32_t v);
    OpValue(int64_t v);
    OpValue(uint64_t v);
    OpValue(float v);
    OpValue(double v);
    OpValue(const char *str);
    OpValue(const std::string &str);
    OpValue(void *p);

    OpValue(uint8_t *cmd_, int32_t len);

    OpValue(const CmdValue &cmd_);

    /* operator=*/
    OpValue &operator=(int8_t v);
    OpValue &operator=(uint8_t v);
    OpValue &operator=(int16_t v);
    OpValue &operator=(uint16_t v);
    OpValue &operator=(int32_t v);
    OpValue &operator=(uint32_t v);
    OpValue &operator=(int64_t v);
    OpValue &operator=(uint64_t v);
    OpValue &operator=(float v);
    OpValue &operator=(double v);
    OpValue &operator=(const char *str);
    OpValue &operator=(const std::string &str);
    OpValue &operator=(void *p);
    OpValue &operator<<(const OpValue &value);
    OpValue &operator<<(const uint8_t value);
    OpValue operator>>(const int32_t at);
    CmdValue GenCmd(int32_t pos_ = 0, int32_t len_ = -1) const;
    virtual ~OpValue();
    bool IsString() const;
    bool IsDigital() const;
    bool IsInteger() const;
    bool IsFloat() const;

    int64_t Integer() const;
    double Float() const;

    typedef enum { ADD, SUB, MUL, DIV, MOD, XOR } OP_E;
    static OpValue calc(OP_E op, const OpValue &value1, const OpValue &value2);
    OpValue operator+(const OpValue &value);
    OpValue operator-(const OpValue &value);
    OpValue operator*(const OpValue &value);
    OpValue operator/(const OpValue &value);
    OpValue operator%(const OpValue &value);
    OpValue operator^(const OpValue &value);

    int32_t GetByte() const;
    void Show();

    std::string toString();

    TYPE_DEFINE type;
    union Udata {
        Udata()
        {
            u64 = 0;
            cmd.Zero();
        };
        ~Udata() {};
        int8_t s8;
        uint8_t u8;
        int16_t s16;
        uint16_t u16;
        int32_t s32;
        uint32_t u32;
        int64_t s64;
        uint64_t u64;
        float f32;
        double f64;
        std::string str;
        char buf[8];
        void *pointer;
        CmdValue cmd;
    } data;
    std::vector<OpValue> array;

private:
    void release();
    void copydata(const OpValue &value);
};
} // namespace libxcom

#endif // LIBCOM_SRC_OPVALUE_H
